package com.toommi.refuse.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.toommi.refuse.common.enums.*;
import com.toommi.refuse.common.util.DateUtil;
import com.toommi.refuse.entity.*;
import com.toommi.refuse.enums.RecycleRecordExceptionEnum;
import com.toommi.refuse.exception.RecycleRecordException;
import com.toommi.refuse.mapper.*;
import com.toommi.refuse.service.AppUserPayStatisticsService;
import com.toommi.refuse.service.AppUserSubStatisticsService;
import com.toommi.refuse.service.RecycleRecordService;
import com.toommi.refuse.service.RecycleStatisticsService;
import com.toommi.refuse.tools.ParamCheckUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yangg
 * @since 2019-08-01 12:10
 */
@Slf4j
@Service
@AllArgsConstructor
public class RecycleRecordServiceImpl implements RecycleRecordService {

    private RecycleRecordMapper recordMapper;

    private AppUserMapper appUserMapper;

    private WechatUserMapper wechatUserMapper;

    private RefuseTypeMapper refuseTypeMapper;

    private HouseholdMapper householdMapper;

    private WechatUserHouseholdMapper wechatUserHouseholdMapper;

    private BuildingMapper buildingMapper;

    private NeighbourhoodMapper neighbourhoodMapper;

    private RecycleStatisticsService statisticsService;

    private AppUserPayStatisticsService appUserPayStatisticsService;

    private AppUserSubStatisticsService subStatisticsService;


    /**
     * 保存圖片
     *
     * @param stream
     * @param path
     * @param filename
     */
    private void SaveFileFromInputStream(InputStream stream, String path, String filename) {
        FileOutputStream fs;
        try {
            fs = new FileOutputStream(path + "/" + filename);
            byte[] buffer = new byte[1024 * 1024];
            @SuppressWarnings("unused")
            int bytesum = 0;
            int byteread = 0;
            while ((byteread = stream.read(buffer)) != -1) {
                bytesum += byteread;
                fs.write(buffer, 0, byteread);
                fs.flush();
            }
            fs.close();
            stream.close();
        } catch (Exception e) {
            e.printStackTrace();

        }
    }
    @Override
    @Transactional
    public void addRecycleRecord(RecycleRecord record, MultipartFile filerefuse, MultipartFile openfilec) throws RecycleRecordException {

        boolean appUser = false;
        boolean recycle = false;
        switch (RefuseTypeEnum.getTypeByCode(record.getRefuseType())) {

            case NORMAL:
                generateNormalRecord(record);
                break;
            case RECYCLABLE:
                generateRecycleRecord(record);
                appUser = true;
                recycle = true;
                break;
            case LARGE:
                generateLargeRecord(record);
                appUser = true;
                break;
            case END:
                break;
            default:
                break;
        }
        String path=null;
        String path1=null;
        if(filerefuse!=null&&openfilec!=null){
            log.info("ddddd有图片----------");
            try{
                String filename = filerefuse.getOriginalFilename();// 获取文件名
                int index = filename.lastIndexOf(".");
                String png = filename.substring(index + 1, filename.length());
                String name = String.valueOf(new Date().getTime());
                SaveFileFromInputStream(filerefuse.getInputStream(), "/opt/epage" + File.separator,
                        name + "." + png);
                path="/image" + File.separator+ name + "." + png;

                String filename1 = openfilec.getOriginalFilename();// 获取文件名
                int index1= filename1.lastIndexOf(".");
                String png1 = filename1.substring(index1 + 1, filename1.length());
                String name1 = String.valueOf(new Date().getTime())+"1";
                SaveFileFromInputStream(openfilec.getInputStream(), "/opt/epage" + File.separator,
                        name1 + "." + png1);
                path1="/image" + File.separator+ name1 + "." + png1;
                record.setImg(path);
                record.setImg1(path1);
            }catch (Exception e){
                throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_HOUSEHOLDCODE_NULL);
            }
        }
        completeRecord(record);
        recordMapper.insert(record);
        //生成居民记录统计
        statisticsService.addRecycleStatistics(Long.valueOf(record.getWechatUserId()), record.getWeight() == null ? 0.0 : record.getWeight(),
                record.getMoney() == null ? new BigDecimal(0.0) : record.getMoney(), record.getRefuseType());
        //生成操作员统计记录
        if (appUser) {
            appUserPayStatisticsService.addStatistics(record.getAppUserId(), record.getMoney(), record.getRefuseType());
        }
        if (recycle) {
            subStatisticsService.addStatistics(record.getAppUserId(), record.getWeight(), record.getSubRefuseTypeId());
        }
    }


    @Override
    public Object findRecycleRecords(int pageNum, int pageSize, long wechatUserId,
                                                      long appUserId, long householdId,
                                                      long startTime, long endTime,
                                                      int status, String refuseType) {
        PageHelper.startPage(pageNum, pageSize);

        RecycleRecordExample example = new RecycleRecordExample();
        RecycleRecordExample.Criteria criteria = example.createCriteria();

//        if (wechatUserId > 0 && householdId <= 0) {
//            WechatUserHouseholdExample wechatUserHouseholdExample = new WechatUserHouseholdExample();
//            wechatUserHouseholdExample.createCriteria().andWechatUserIdEqualTo(wechatUserId);
//
//            WechatUserHousehold userHousehold = wechatUserHouseholdMapper.selectOneByExample(wechatUserHouseholdExample);
//            if (userHousehold == null) {
//                return new PageInfo<>();
//            }
//            householdId = userHousehold.getHouseholdId();
//        }
//        if (householdId > 0) {
//            criteria.andHouseholdIdEqualTo(householdId);
//        }
        if (appUserId > 0) {
            criteria.andAppUserIdEqualTo(appUserId);
        }
        if (startTime > 0) {
            criteria.andCreateTimeGreaterThanOrEqualTo(startTime);
        }
        if (endTime > 0) {
            criteria.andCreateTimeLessThanOrEqualTo(endTime);
        }
        if (status > 0) {
            criteria.andStatusEqualTo(status);
        }
        if (StringUtils.isNotEmpty(refuseType)) {
            criteria.andRefuseTypeEqualTo(refuseType);
        }
        PageInfo<RecycleRecord> pageInfo = new PageInfo<RecycleRecord>(recordMapper.selectByExample(example));
        Map<String,Object> result=new HashMap<String,Object>();

        //把唯一编码
        result.put("count", pageInfo.getTotal());
        result.put("data", pageInfo.getList());
//        result.put("code", 0);
//        result.put("msg", "");
        return result;
    }

    @Override
    public RecycleRecord findDetail(long id) {
        return recordMapper.selectByPrimaryKey(id);
    }

    @Override
    public void updateRecycleRecord(RecycleRecord record) throws RecycleRecordException {

        //更新内容为 正确性判断状态及支付状态
        RecycleRecord recycleRecord = recordMapper.selectByPrimaryKey(record.getId());
        if (recycleRecord == null) {
            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_RECORD_NULL);
        }
        if (record.getStatus() != null && record.getStatus() > 0) {
            //更新正确性判断
            if (!YNStatusEnum.hasValue(record.getStatus())) {
                throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_STATUS);
            }
            recycleRecord.setStatus(record.getStatus());
        }

        if (record.getPayStatus() != null && record.getPayStatus() > 0) {
            //更新正确性判断
            if (!PayStatusEnum.hasValue(record.getPayStatus())) {
                throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_STATUS);
            }
            recycleRecord.setStatus(record.getPayStatus());
        }

        recordMapper.updateByPrimaryKey(recycleRecord);

    }

    @Override
    public String getCorrectRatio(long wechatUserId, long startTime, long endTime) {

        //获取被判断为正确的投放记录总数
        RecycleRecordExample example = new RecycleRecordExample();
        example.createCriteria().andWechatUserIdEqualTo(wechatUserId)
                .andCreateTimeGreaterThanOrEqualTo(startTime)
                .andCreateTimeLessThanOrEqualTo(endTime)
                .andStatusEqualTo(YNStatusEnum.YES.getCode());

        RecycleRecordExample example2 = new RecycleRecordExample();
        example2.createCriteria().andWechatUserIdEqualTo(wechatUserId)
                .andCreateTimeGreaterThanOrEqualTo(startTime)
                .andCreateTimeLessThanOrEqualTo(endTime)
                .andStatusEqualTo(YNStatusEnum.NO.getCode());
        int correctCount = recordMapper.selectCountByExample(example);
        int falseCount = recordMapper.selectCountByExample(example2);
        if (correctCount + falseCount == 0) {
            return "0";
        }
        BigDecimal percent=new BigDecimal(correctCount).divide(new BigDecimal(correctCount).add(new BigDecimal(falseCount)),2,BigDecimal.ROUND_HALF_UP);
       // double percent = correctCount / (correctCount + falseCount);
        NumberFormat numberFormat = NumberFormat.getPercentInstance();
        numberFormat.setMaximumFractionDigits(2);
        return numberFormat.format(percent.doubleValue());
    }

    /**
     * 构建大件垃圾回收记录
     *
     * @param record 大件垃圾回收记录
     * @throws RecycleRecordException 校验异常
     */
    private void generateLargeRecord(RecycleRecord record) throws RecycleRecordException {

        ParamCheckUtil.checkLargeRecycleRecord(record);
        //校验大件类型

        long subTypeId = record.getSubRefuseTypeId();

        RefuseType refuseType = refuseTypeMapper.selectByPrimaryKey(subTypeId);
        if (refuseType == null) {
            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_SUBREFUSE_TYPE_NULL);
        }
        record.setSubRefuseTypeName(refuseType.getName());

        //校验回收员数据

        long appUserId2 = record.getAppUserId();

        AppUser appUser2 = appUserMapper.selectByPrimaryKey(appUserId2);
        if (appUser2 == null) {
            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_APPUSER_NULL);
        }
        record.setAppUserName(appUser2.getName());
        record.setAppUserPhone(appUser2.getPhone());
        RecycleRecordExample example3 = new RecycleRecordExample();
        example3.createCriteria().andQrcodeEqualTo(record.getQrcode())
                .andRefuseTypeEqualTo(RefuseTypeEnum.LARGE.getCode());
        //ID为自动生成，按ID降序则取到最新的
        example3.setOrderByClause(" id desc");

        RecycleRecord recycleRecord3 = null;
        List<RecycleRecord> recycleRecordList = recordMapper.selectByExample(example3);
        if (recycleRecordList != null && !recycleRecordList.isEmpty()) {
            recycleRecord3 = recycleRecordList.get(0);
        }
        if (recycleRecord3 == null || !DateUtil.inSameMonth(recycleRecord3.getCreateTime(),
                System.currentTimeMillis())) {
            record.setMoneyBefore(new BigDecimal(0.0));
        } else {
            record.setMoneyBefore(recycleRecord3.getMoneyNow());
        }
        //累计
        record.setMoneyNow(record.getMoney().add(record.getMoneyBefore()));

    }

    /**
     * 构建可回收垃圾回收记录
     *
     * @param record 回收记录
     * @throws RecycleRecordException 校验异常
     */
    private void generateRecycleRecord(RecycleRecord record) throws RecycleRecordException {
        ParamCheckUtil.checkRecyclableRecycleRecord(record);
        // 校验二级类型

        if (!RecyclableTrashTypeEnum.hasValue(record.getSubRefuseTypeId())) {
            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_SUBREFUSE_TYPE_NULL);
        }
        if (!RecyclableTrashTypeEnum.hasValue(Long.valueOf(record.getSupRefuseTypeId()))) {
            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_SUBREFUSE_TYPE_NULL);
        }
        record.setSubRefuseTypeName(RecyclableTrashTypeEnum.getType(record.getSubRefuseTypeId()).getNote());
        record.setSupRefuseTypeName(RecyclableTrashTypeEnum.getType(Long.valueOf(record.getSupRefuseTypeId())).getNote());
        //校验回收员数据

        long appUserId = record.getAppUserId();

        AppUser appUser = appUserMapper.selectByPrimaryKey(appUserId);
        if (appUser == null) {
            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_APPUSER_NULL);
        }
        record.setAppUserName(appUser.getName());
        record.setAppUserPhone(appUser.getPhone());

        RecycleRecordExample example2 = new RecycleRecordExample();
        example2.createCriteria().andRefuseTypeEqualTo(RefuseTypeEnum.RECYCLABLE.getCode());
        //ID为自动生成，按ID降序则取到最新的
        example2.setOrderByClause(" id desc");

        RecycleRecord recycleRecord2 = null;
        List<RecycleRecord> recycleRecordList = recordMapper.selectByExample(example2);
        if (recycleRecordList != null && !recycleRecordList.isEmpty()) {
            recycleRecord2 = recycleRecordList.get(0);
        }

        if (recycleRecord2 == null || !DateUtil.inSameMonth(recycleRecord2.getCreateTime(),
                System.currentTimeMillis())) {
            record.setWeightBefore(0.0);
            record.setMoneyBefore(new BigDecimal(0.0));
        } else {
            record.setWeightBefore(recycleRecord2.getWeightNow());
            record.setMoneyBefore(recycleRecord2.getMoneyNow());
        }
        //累计
        record.setWeightNow(new BigDecimal(record.getWeight()).add(new BigDecimal(record.getWeightBefore())).doubleValue());
        record.setMoneyNow(record.getMoney().add(record.getMoneyBefore()));

    }

    /**
     * 构建普通垃圾回收记录
     *
     * @param record 回收记录
     * @throws RecycleRecordException 校验异常
     */
    private void generateNormalRecord(RecycleRecord record) throws RecycleRecordException {
        //普通垃圾回收
        ParamCheckUtil.checkNormalRecycleRecord(record);
        //计算累计重量和累计金额,方式为根据户号（qrcode/householdid）查询出最新的一条普通垃圾回收记录
        //判断该记录和当前时间是否为同一个月，是则以该记录为基础计算结果，否则说明当月尚无记录，从0计算

        RecycleRecordExample example = new RecycleRecordExample();
        example.createCriteria().andQrcodeEqualTo(record.getQrcode())
                .andRefuseTypeEqualTo(RefuseTypeEnum.NORMAL.getCode());
        //ID为自动生成，按ID降序则取到最新的
        example.setOrderByClause(" id desc");
        RecycleRecord recycleRecord = null;
        List<RecycleRecord> recycleRecordList = recordMapper.selectByExample(example);
        if (recycleRecordList != null && !recycleRecordList.isEmpty()) {
            recycleRecord = recycleRecordList.get(0);
        }

        if (recycleRecord == null || !DateUtil.inSameMonth(recycleRecord.getCreateTime(), System.currentTimeMillis())) {
            record.setWeightBefore(0.0);
        } else {
            record.setWeightBefore(recycleRecord.getWeightNow());
        }
        //累计
        record.setWeightNow(new BigDecimal(record.getWeight()).add(new BigDecimal(record.getWeightBefore())).doubleValue());
        record.setStatus(YNStatusEnum.WAITING.getCode());

        record.setSubRefuseTypeName(NormalTrashTypeEnum.getTypeById(record.getSubRefuseTypeId()).getNote());

    }

    /**
     * 构建完整的记录信息
     *
     * @param record 记录
     * @throws RecycleRecordException 校验异常
     */
    private void completeRecord(RecycleRecord record) throws RecycleRecordException {
        //补全户号信息


        Map<String,Object> UserInfo=wechatUserMapper.getUserBuildInfo(record.getQrcode());
//        HouseholdExample householdExample = new HouseholdExample();
//        householdExample.createCriteria().andCodeEqualTo(record.getQrcode());
//        Household household = householdMapper.selectOneByExample(householdExample);
//        if (household == null) {
//            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_HOUSEHOLDCODE_NULL);
//        }
//        //查找户主
//        WechatUserHouseholdExample wechatUserHouseholdExample = new WechatUserHouseholdExample();
//        wechatUserHouseholdExample.createCriteria().andHouseholdIdEqualTo(household.getId())
//                .andRoleEqualTo(FamilyRoleEnum.MASTER.getCode());
//        WechatUserHousehold wechatUserHousehold = wechatUserHouseholdMapper.selectOneByExample(wechatUserHouseholdExample);
//        if (wechatUserHousehold == null) {
//            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_HOUSEHOLDCODE_NULL);
//        }
//        //获取用户信息-户主
//       Map<String,Object> wechatUser = wechatUserMapper.getUserInfo(wechatUserHousehold.getWechatUserId());
//        if (wechatUser == null) {
//            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_HOUSEHOLDCODE_NULL);
//        }
        record.setWechatUserId(String.valueOf(UserInfo.get("uid")));
        record.setWechatUserName(String.valueOf(UserInfo.get("username")));
        record.setWechatUserAddress(String.valueOf(UserInfo.get("address")));

        record.setHouseholdId(Long.valueOf(String.valueOf(UserInfo.get("uid"))));
        record.setHouseholdName(String.valueOf(UserInfo.get("mph")));

       // record.setBuildingId(String.valueOf(UserInfo.get("uid")));



//        record.setHouseholdId(Long.valueOf(String.valueOf(UserInfo.get("household_id"))));
//        record.setHouseholdName(String.valueOf(UserInfo.get("mph")));



//        Building building = buildingMapper.selectByPrimaryKey(household.getBuilding());
//        if (building == null) {
//            throw new RecycleRecordException(RecycleRecordExceptionEnum.INVALID_HOUSEHOLDCODE_NULL);
//        }
        record.setBuildingName(String.valueOf(UserInfo.get("ldname")));
        record.setNeighbourhoodId(Long.valueOf(String.valueOf(UserInfo.get("xqid"))));

        record.setNeighbourhoodName(String.valueOf(UserInfo.get("xqname")));

        record.setRefuseTypeName(RefuseTypeEnum.getTypeByCode(record.getRefuseType()).getType());

        record.setCreateTime(System.currentTimeMillis());
        record.setUpdateTime(System.currentTimeMillis());
    }

}
